package com.djhu.freepartner.web.service.impl;

import com.djhu.freepartner.utils.GeneralUtils;
import com.djhu.freepartner.web.control.model.VerifiyCode;
import com.djhu.freepartner.web.service.VerifiyCodeService;
import com.djhu.freepartner.web.support.VerifiyCodeGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifiyCodeServiceImpl implements VerifiyCodeService {

    private final static int DEFAULT_WIDTH = 70;
    private final static int DEFAULT_HEIGHT = 35;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${spring.freepartner.code_time:60}")
    private Integer code_time;

    @Override
    public VerifiyCode create() {
        return create(DEFAULT_WIDTH,DEFAULT_HEIGHT);
    }

    @Override
    public VerifiyCode create(int width, int height){
        VerifiyCodeGenerator verifiyCodeGenerator = new VerifiyCodeGenerator(width,height);
        BufferedImage image = verifiyCodeGenerator.getImage();
        String text = verifiyCodeGenerator.getText();
        String validateCode = GeneralUtils.getUUID();
        log.info("validateCode is {},text is {}",validateCode,text);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", byteArrayOutputStream);

            BASE64Encoder encoder = new BASE64Encoder();
            String png_base64 =  encoder.encodeBuffer(byteArrayOutputStream.toByteArray()).trim();
            png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");
            redisTemplate.opsForValue().set(validateCode,text,code_time, TimeUnit.SECONDS);
            log.info("validateCode is {},text is {},base64 is {}",validateCode,text,png_base64);
            VerifiyCode verifiyCode = new VerifiyCode(png_base64,validateCode,text);
            return verifiyCode;
        } catch (IOException e) {
            e.printStackTrace();
            log.error("create VerifiyCode error!!!",e);
        }finally {
            try {
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public boolean validate(String code, String validate) {
        if (StringUtils.isAnyEmpty(code,validate)){
            return false;
        }else {
            String validateCode = String.valueOf( redisTemplate.opsForValue().get(validate));
            if (StringUtils.isEmpty(validateCode)){
                return false;
            }
            if (code.equals(validateCode)){
                return true;
            }else {
                return false;
            }
        }
    }
}
